package cn.stylefeng.guns.modular.account.service.impl;

import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.constant.ConstantsHolderContext;
import cn.stylefeng.guns.modular.account.entity.Account;
import cn.stylefeng.guns.modular.account.mapper.AccountMapper;
import cn.stylefeng.guns.modular.account.model.params.AccountParam;
import cn.stylefeng.guns.modular.account.model.result.AccountResult;
import  cn.stylefeng.guns.modular.account.service.AccountService;
import cn.stylefeng.guns.modular.deduct.model.params.DeductParam;
import cn.stylefeng.guns.modular.deduct.service.DeductService;
import cn.stylefeng.guns.modular.recharge.model.params.RechargeParam;
import cn.stylefeng.guns.modular.recharge.service.RechargeService;
import cn.stylefeng.guns.sys.core.exception.enums.BizExceptionEnum;
import cn.stylefeng.roses.core.util.ToolUtil;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 账户表 服务实现类
 * </p>
 *
 * @author liuqiang
 * @since 2020-02-10
 */
@Service
public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> implements AccountService {

    @Autowired
    private DeductService deductService;

    @Autowired
    private RechargeService rechargeService;

    @Override
    public void add(AccountParam param){
        AccountResult accountResult = getByPhone(param.getPhone());
        if(accountResult != null){
            throw new ServiceException(BizExceptionEnum.USER_ALREADY_EXIST);
        }
        Account entity = getEntity(param);
        //账号余额初始设置为0 防止用户自己添加
        entity.setBalance(new BigDecimal(0));
        this.save(entity);
    }

    @Override
    public void delete(AccountParam param){
        this.removeById(getKey(param));
    }

    @Override
    public void update(AccountParam param){
        Account oldEntity = getOldEntity(param);
        Account newEntity = getEntity(param);
        ToolUtil.copyProperties(newEntity, oldEntity);
        this.updateById(newEntity);
    }

    @Override
    public AccountResult findBySpec(AccountParam param){
        return null;
    }

    @Override
    public List<AccountResult> findListBySpec(AccountParam param){
        return null;
    }

    @Override
    public LayuiPageInfo findPageBySpec(AccountParam param){
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageList(pageContext, param);
        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    public LayuiPageInfo findPageRemindList(AccountParam param) {
        Page pageContext = getPageContext();
        param.setBalance(ConstantsHolderContext.getRechargeRemind());
        IPage page = this.baseMapper.remindPageList(pageContext, param);
        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    public AccountResult getByPhone(String phone) {
        return this.baseMapper.getByPhone(phone);
    }

    @Override
    public void deductByPhone(String phone, BigDecimal totalPrice) {
        AccountResult byPhone = getByPhone(phone);
        BigDecimal subtract = byPhone.getBalance().subtract(totalPrice);
        byPhone.setBalance(subtract);

        this.baseMapper.updateBalance(byPhone);
    }

    @Override
    public void addByPhone(String phone, BigDecimal amount) {
        AccountResult byPhone = getByPhone(phone);
        if(byPhone != null){
            BigDecimal add = byPhone.getBalance().add(amount);
            byPhone.setBalance(add);

            this.baseMapper.updateBalance(byPhone);
        }
    }

    @Override
    public BigDecimal updateByPhone(String mobile, BigDecimal totalPrice, Integer start_time) {
        AccountResult byPhone = getByPhone(mobile);
        AccountParam param = new AccountParam();
        param.setId(byPhone.getId());
        //扣款
        BigDecimal balance = byPhone.getBalance().subtract(totalPrice);
        param.setBalance(balance);
        //消费金额累计
        BigDecimal consumeAmount = byPhone.getConsumeAmount().add(totalPrice);
        param.setConsumeAmount(consumeAmount);
        //上课次数累计
        param.setCourseTimes(byPhone.getCourseTimes()+1);

        //最后上课时间
        Date lastCourseTime = byPhone.getLastCourseTime();
        if(lastCourseTime != null){
            boolean updateAble =  lastCourseTime.getTime()/1000 > start_time ? false : true;
            if(updateAble){
                param.setLastCourseTime(new Date(start_time*1000L));
            }
        }else {
            param.setLastCourseTime(new Date(start_time*1000L));
        }

        this.update(param);
        return balance;
    }

    @Override
    public LayuiPageInfo statistic(AccountParam accountParam) {
        LayuiPageInfo pageInfo = this.findPageBySpec(accountParam);
        List<AccountResult> list = pageInfo.getData();
        for(AccountResult account: list){

            //累计消费
            DeductParam deductParam = new DeductParam();
            deductParam.setPhone(account.getPhone());
            deductParam.setStartTime(accountParam.getStartTime());
            deductParam.setEndTime(accountParam.getEndTime());
            BigDecimal consumeAmount = deductService.sumConsumeAmount(deductParam);
            account.setConsumeAmount(consumeAmount);


            //累计充值
            RechargeParam rechargeParam = new RechargeParam();
            rechargeParam.setPhone(account.getPhone());
            rechargeParam.setStartTime(accountParam.getStartTime());
            rechargeParam.setEndTime(accountParam.getEndTime());
            BigDecimal accumulateRecharge = rechargeService.accumulateRecharge(rechargeParam);
            account.setRechargeAmount(accumulateRecharge);

        }
        return pageInfo;
    }

    private Serializable getKey(AccountParam param){
        return param.getId();
    }

    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    private Account getOldEntity(AccountParam param) {
        return this.getById(getKey(param));
    }

    private Account getEntity(AccountParam param) {
        Account entity = new Account();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }
}
